package com.yiwyn.bytebuddy.proxy;

import com.yiwyn.bytebuddy.proxy.advice.SayHelloAdvice;
import com.yiwyn.bytebuddy.service.HelloService;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.matcher.ElementMatchers;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Slf4j
//@Component
public class ByteBuddyHelloServiceProcessor implements BeanPostProcessor, BeanClassLoaderAware {

    private ClassLoader classLoader;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

        Class<?> targetClass = AopUtils.getTargetClass(bean);

        if (HelloService.class.isAssignableFrom(targetClass)) {
            HelloService helloService = null;
            try {
                helloService = new ByteBuddy()
                        .subclass(HelloService.class)
                        .method(ElementMatchers.named("sayHello"))
//                        .intercept(FixedValue.value("Hello World ByteBuddy!"))
                        .intercept(Advice.to(SayHelloAdvice.class))
                        .make()
                        .load(classLoader)
                        .getLoaded()
                        .newInstance();
            } catch (Exception e) {
                throw new BeanCreationException("Could not create ByteBuddy proxy", e);
            }
            log.info("处理到Service类");
            return helloService;
        }

        return bean;

    }


    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }
}


